﻿using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

namespace PmSoft.Core.EventBus;

/// <summary>
/// 实现分布式事件总线
/// // 注册分布式事件总线
/// //builder.Services.AddSingleton<IEventBus, DistributedEventBus>(sp =>
/// //new DistributedEventBus(sp.GetRequiredService<IMessageQueue>(), sp.GetRequiredService<IServiceScopeFactory>()));
/// //// 注册消息队列实现（假设使用 RabbitMQ）
/// //builder.Services.AddSingleton<IMessageQueue, RabbitMQService>();
/// </summary>
public class DistributedEventBus : IEventBus
{
	private readonly IMessageQueue _messageQueue; // 假设有一个消息队列接口
	private readonly IServiceScopeFactory _scopeFactory;

	public DistributedEventBus(IMessageQueue messageQueue, IServiceScopeFactory scopeFactory)
	{
		_messageQueue = messageQueue;
		_scopeFactory = scopeFactory;
	}

	// 异步发布（等待执行）
	public async Task PublishAsync<TEvent>(TEvent args) where TEvent : CommonEventArgs
	{
		await _messageQueue.PublishAsync(args);
	}

	// 同步发布（阻塞执行）
	public void Publish<TEvent>(TEvent args) where TEvent : CommonEventArgs
	{
		_messageQueue.PublishAsync(args).GetAwaiter().GetResult();
	}

	// 发布后无需等待（后台执行）
	public void FireAndForget<TEvent>(TEvent args) where TEvent : CommonEventArgs
	{
		var clonedEvent = CloneEvent(args);
		Task.Run(async () =>
		{
			try
			{
				await _messageQueue.PublishAsync(clonedEvent);
			}
			catch (Exception ex)
			{
				using (var scope = _scopeFactory.CreateScope())
				{
					var logger = scope.ServiceProvider.GetService<ILogger<DistributedEventBus>>();
					logger?.LogError(ex, $"分布式事件发布失败：{typeof(TEvent).Name}");
				}
			}
		});
	}

	// 深拷贝事件对象
	private TEvent CloneEvent<TEvent>(TEvent args) where TEvent : CommonEventArgs
	{
		var json = System.Text.Json.JsonSerializer.Serialize(args);
		return System.Text.Json.JsonSerializer.Deserialize<TEvent>(json)!;
	}
}
